package online.loveplay.web.web.controller;

import cn.hutool.crypto.SecureUtil;
import online.loveplay.api.BusinessException;
import online.loveplay.api.ConstUtil;
import online.loveplay.api.IpUtil;
import online.loveplay.api.dto.ManagerDto;
import online.loveplay.api.service.IpAddressService;
import online.loveplay.api.service.ManagerService;
import online.loveplay.api.vo.ManagerVo;
import online.loveplay.web.safe.config.JwtUtil;
import online.loveplay.web.safe.config.RedisCache;
import online.loveplay.web.safe.entity.LoginUser;
import online.loveplay.web.safe.entity.ResponseResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Objects;


/**
 * 登录Controller
 *
 * @author 阿前
 * 2022年1月4日09:48:21
 */
@RestController
@RequestMapping("")
public class LoginController extends BaseController {

    @DubboReference
    private ManagerService managerService;
    @DubboReference
    private IpAddressService ipAddressService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    /*
     * 响应验证码页面
     * @return
     */
   /* @ResponseBody
    @RequestMapping(value="/validateCode", method = RequestMethod.GET)
    public String validateCode(HttpServletRequest request,HttpServletResponse response) throws Exception{
        // 设置响应的类型格式为图片格式
        response.setContentType("image/jpeg");
        //禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        HttpSession session = request.getSession();

        ValidateCode vCode = new ValidateCode(120,40,5,100);
        session.setAttribute("code", vCode.getCode());
        vCode.write(response.getOutputStream());
        return null;
    } */

    /**
     * 向邮箱发送验证码 邮箱便是以后的用户名
     *
     * @param username 用户名
     * @return result
     */
    @PostMapping("/login/sendOutEmail")
    public ResponseResult sendOutEmail(String username) {
        ResponseResult result = new ResponseResult();
        //发送邮箱信息
        managerService.sendOutEmail(username);
        return result;
    }

    /**
     * 登录
     *
     * @param loginForm     登录人信息
     * @param bindingResult 参数验证
     * @return result
     */
    @PostMapping("/login/login")
    public ResponseResult loginVer(ManagerVo loginForm, BindingResult bindingResult) {
        ResponseResult result = new ResponseResult();
        // 认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginForm.getUsername(), loginForm.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        // 认证没通过
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("用户名或密码错误!");
        }
        // 认证通过 生成jwt
        LoginUser manager = (LoginUser) authenticate.getPrincipal();
        String userId = manager.getId().toString();
        String jwt = JwtUtil.createJWT(userId);
        if (manager.getType().equals(ConstUtil.BOLG_MIN)) {
            throw new BusinessException("博主无权限登录后台");
        }

        //更新ip
        ipAddressService.update(manager.getId(), IpUtil.getIpAddr());

        // 认证通过 存入 redis
        redisCache.setCacheObject("login:" + userId, manager);
        result.setData(manager);
        result.setToken(jwt);

        return result;
    }

    /**
     * 登录
     *
     * @param loginForm     登录人信息
     * @param bindingResult 参数验证
     * @return result
     */
    @PostMapping("/login")
    public ResponseResult login(ManagerVo loginForm, BindingResult bindingResult) {
        ResponseResult result = new ResponseResult();

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginForm.getUsername(), loginForm.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        // 认证没通过
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("用户名或密码错误!");
        }
        // 认证通过 生成jwt
        LoginUser manager = (LoginUser) authenticate.getPrincipal();
        String userId = manager.getId().toString();
        String jwt = JwtUtil.createJWT(userId);

        //更新ip
        ipAddressService.update(manager.getId(), IpUtil.getIpAddr());
        manager.setPassword(null);
        manager.setAgiPassword(null);
        result.setData(manager);
        result.setToken(jwt);
        // 认证通过 存入 redis
        redisCache.setCacheObject("login:" + userId, manager);
        return result;
    }

    /**
     * 博主注册
     *
     * @param manager 注册用户信息
     * @return result
     */
    @PostMapping("/register")
    public ResponseResult register(ManagerVo manager) {
        ResponseResult result = new ResponseResult();
        manager.setType("博主");
        ManagerDto manager1 = managerService.saveManager(manager);
        result.setData(manager1);
        return result;
    }

    /**
     * 返回未登录状态码
     */
    @RequestMapping("/login/noLogin")
    public ResponseResult noLogin() {
        ManagerDto managerDto = getManager();
        Integer userId = managerDto.getId();
        // 清空redis
        redisCache.deleteObject("login:" + userId);
        return new ResponseResult(200, "退出成功");
    }

}
